package com.umeox.recorder.data

import android.annotation.SuppressLint
import android.media.MediaPlayer
import android.os.Handler
import android.os.Message
import android.util.Log

class MediaManager @SuppressLint("HandlerLeak") private constructor() {
    private var mMediaPlayer: MediaPlayer?
    private val mHandler: Handler

    private var mPrepared = false

    /**
     * 播放完成回调
     */
    var onPlayComplete: (() -> Unit)? = null

    /**
     * 播放进度回调
     */
    var onProgress: ((progress: Int) -> Unit)? = null

    init {
        mMediaPlayer = MediaPlayer()
        mHandler = object : Handler() {
            override fun handleMessage(msg: Message) {
                mMediaPlayer?.currentPosition?.let {
                    onProgress?.invoke(it)
                }
                if (mMediaPlayer?.isPlaying == true) {
                    sendEmptyMessageDelayed(WHAT, PROGRESS_FREQUENCY)
                }
            }
        }
    }

    fun prepare(filePath: String, prepareComplete: () -> Unit) {
        Log.d(TAG, "start: $filePath")
        val player = MediaPlayer().also {
            mMediaPlayer = it
        }
        try {
            try {
                player.reset()
            } catch (e: Exception) {
                Log.e(TAG, "prepare: ", e)
            }

            player.setDataSource(filePath)
            player.prepareAsync()
            player.setOnPreparedListener { mp: MediaPlayer? ->
                Log.d(TAG, "onPrepared: length=${mp?.duration}")
                mHandler.sendEmptyMessage(WHAT)
                mPrepared = true
                prepareComplete.invoke()
            }

            player.setOnCompletionListener { mp: MediaPlayer? ->
                Log.d(TAG, "onCompletion: ")
                onPlayComplete?.invoke()
            }
        } catch (e: Exception) {
            Log.e(TAG, "start: ", e)
        }
    }

    fun stop() {
        try {
            mHandler.removeCallbacksAndMessages(null)
            if (mMediaPlayer != null && mMediaPlayer!!.isPlaying) {
                mMediaPlayer!!.stop()
            }
        } catch (e: Exception) {
            Log.e(TAG, "stop: ", e)
        }
    }

    fun release() {
        try {
            mHandler.removeCallbacksAndMessages(null)
            mMediaPlayer?.let {
                it.release()
            }
            mMediaPlayer = null
        } catch (e: Exception) {
            Log.e(TAG, "release: ", e)
        }
    }

    fun play() {
        val player = mMediaPlayer ?: return
        player.start()
        mHandler.removeCallbacksAndMessages(null)
        mHandler.sendEmptyMessage(WHAT)
    }

    fun pause() {
        val player = mMediaPlayer ?: return
        if (!player.isPlaying) return
        player.pause()
        mHandler.removeCallbacksAndMessages(null)
    }

    /**
     * 获取时长
     *
     * @return 时长毫秒值
     */
    fun getLength(): Int {
        return if (mPrepared) {
            mMediaPlayer?.duration ?: 0
        } else {
            0
        }
    }

    /**
     * 获取播放进度
     *
     * @return 播放进度毫秒值，未初始化会返回null
     */
    fun getProgress(): Int? {
        return mMediaPlayer?.currentPosition
    }

    /**
     * 设置播放进度
     *
     * @param progressMillis 进度毫秒值
     */
    fun setProgress(progressMillis: Int) {
        if (!mPrepared) return
        mMediaPlayer?.seekTo(progressMillis)
    }

    private object HolderInstance {
        val instance: MediaManager = MediaManager()
    }

    companion object {
        private const val TAG = "MediaPlayerManager"
        private const val PROGRESS_FREQUENCY = 100L
        const val WHAT: Int = 10
        val instance: MediaManager get() = HolderInstance.instance
    }
}
